home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
packet
/
p_tapr
/
tnchst
/
aft.c
next >
Wrap
Text File
|
1992-03-16
|
9KB
|
362 lines
/*****************************************
AFT driver (c) 1991 Howard Goldstein
Permission for non-commercial Amateur Radio
use granted
******************************************/
#define DEBUG 1
/* dumps packets to printf */
/* set to 1 when running under uSoft C */
#define MSDOS 1
#if MSDOS
#include "aft.inc"
#endif
#define AFTMAXFRAMESIZE 350
#include "blp.inc"
/** enable XON/XOFF transparancy **/
#define AFTLEVEL1 1
struct itm_struct
{
char *itm_src ; /* this is the sending task */
char *itm_dest ; /* " " " dest task */
char itm_ctrl ; /* message type */
char *itm_msg ; /* pointer to message */
/* used in AFTRCV to hold
cksum temporarily I hope */
unsigned int msg_len ; /* length of message */
char itm_data[1] ; /* optional area begins
here. allows
buffers to live in mem
contigious to an itm
structure. an n byte
data field could be started
at this offset IF PROPER
allocation is performed! */
};
/* statics for exceedingly simple aft rx driver */
struct itm_struct *aftr_msg; /* when 0, there is no
current buffer ready.
when !0, then the struct
is ready to rcv the next
aft frame */
word aftrstate, aftrlen ;
/* aft rx machine state, and length
at current instant
if in a receive state */
byte *aftrptr; /* pointer used by driver to quickly
insert the char in the rcvd msg */
byte aftrcksum ; /* current receive cksum */
void cdecl aftr_init()
{
aftr_msg = (struct itm_struct *) NULL;
/* null out so no message is waiting*/
aftrstate = AFRHUNT; /* state == hunting for flags */
}
/* runs from executive, if !MSDOS, else is called from char-by-char
driver if MSDOS. processes the AFT message */
int cdecl
aftr_handler( msg )
struct itm_struct *msg;
{
#if MSDOS
byte *c;
byte cksum;
word len;
extern void cdecl aft_in_handler();
struct bframe_struct *bframe; /* blp frame pointer */
if ( msg->msg_len < 1 )
return( FALSE ) ; /* error - too short for
AFT */
/** rest is debug ***/
bframe = (struct bframe_struct *) msg->itm_data+2 ;
/* points to blp frame */
if ( bframe->lcn == BROADCAST_LCN ) /* if bdcst from tnc */
monframe(msg->itm_data+2,msg->msg_len-2); /* display the frame */
/*** note - ought to do above in blp itself... */
#if AFT_FRAME_TRACE
/* take out for now if 0*/
/* just display to console */
c = msg->itm_data; /* set ptr */
cksum = (byte) msg->itm_msg;
#if BROADCAST_TRACE
{
#else
if ( *c != 127 ) /* not bcast lcn? */
{
#endif
printf("received frame len %d checksum %02d DLC cmd %02X lcn %d cmd $%02X\n",
msg->msg_len ,
cksum, *c, *(c+1),*(c+2));
len = msg->msg_len - 1 ; /* take off dlc cmd above */
c += 1;
while ( len-- )
{
printf("%02X,'%c'|", *c, ( *c >= 0x20 ? *c: 0x20 ) );
++c;
}
putchar('\n');
}
#endif
/* send it to the in handler */
aft_in_handler( (struct dlc_frame_struct *) msg->itm_data , msg->msg_len );
free( (byte *) msg );
#else
; /* no function yet for TNC */
#endif
}
/* char-by-character processing */
#if MSDOS
aftr_proc( c )
byte c;
{
byte frame_cksum ; /* holds cksum found in rcvd frame */
switch ( aftrstate ) /* handle according to current state */
{
case AFRHUNT: /* hunting for a sync? */
if ( c == AFT_FLAG ) /* if it's a sync then */
aftrstate = AFRFLAG ; /* wait for non-flag */
break ;
case AFRFLAG: /* hunting for !sync? */
if ( c == AFT_FLAG ) /* if sync then */
break ; /* ignore */
else
{
/* 1st char of new frame here. first, find
an itm to use */
if ( !aftr_msg ) /*need to find an itm? */
{
/* allocate a big enuf buffer
for an intertask msg */
if ( ! (aftr_msg = (struct itm_struct *)
malloc(AFTMAXFRAMESIZE +
sizeof (struct itm_struct)) ) )
{ /*true if could not get a new buf*/
aftrstate = AFRHUNT ;
break ; /** break out of
the big switch **/
}
}
/* now have an itm ready*/
/* set cksum and count to 0 */
aftrlen = 0 ;
aftrcksum = 0 ;
aftrptr = aftr_msg->itm_data ;
/* data ptr at bgng of buffer */
aftrstate = AFRRX;
}
/** and fall through to DATA state **/
case AFRRX: /* basic data state */
/* first see whether the max frame size
has been reached. if so, state>hunt
effectively discards the frame */
if ( aftrlen >= AFTMAXFRAMESIZE )
aftrstate = AFRHUNT ;
else
switch ( c ) /* according to char rcvd */
{
case AFT_DLE: /* escape? */
aftrstate = AFRRX2; /* yes, state->
escape hdlr*/
break ;
case AFT_FLAG: /* end of frame? */
if ( (aftr_msg->msg_len = aftrlen-1) > 0 )
/* store msg len. 'IF len > 0 */
{
frame_cksum = *(aftrptr-1) ;
/* remove value in place
cksum byte will be,
from cksum calc*/
/* aftrcksum -= frame_cksum ; */
aftr_msg->itm_msg = (byte *)
aftrcksum ;
/* REMOVE LATER -
for now store byte
cksum in itm_msg field..
cast needed;itm_msg is a ptr*/
/** test for cksum valid **/
/* if good checksum */
if ( !aftrcksum )
{
#if MSDOS
if ( aftr_handler( aftr_msg ) )
/* release msg in non-dispatched
msdos version if aftr handler
ran ok */
aftr_msg = (struct
itm_struct *) NULL ;
#else
if ( q_task( aftr_handler,
aftr_msg, INT1 ) )
err ; /* error - must decide
what to do when can't queue
a task to service this */
#endif
}
else /* bad checksum */
; /* nop */
}
else ;
/* else nop 'cuz length <1 (i.e.
less than 1 data and 1 cksum byte):
ignore these frames */
aftrstate = AFRFLAG;
break;
default: /* reg char */
aftrcksum += ( *aftrptr++ = c ) ;
++aftrlen;
}
break;
case AFRRX2:
/** previous character received was AFT_DLE **/
/** process aft abort **/
if ( c == AFT_FLAG ) /* if flag occurs after DLE */
aftrstate = AFRFLAG ; /* then change state
( aborts the frame being rcvd */
else
{
/** else this character is xor'd info **/
aftrcksum += ( *aftrptr++ = ( c ^ 0x20 ) ) ;
++aftrlen;
aftrstate = AFRRX;
}
break;
}
}
#endif
/*** TRANSMIT PROCEDURES ***/
void aftt_send_bin( ch ) /* send char to async line transprntly*/
byte ch;
{
PUTAUX( ch ); /** customize for installation **/
}
void aftt_send_data( ch ) /* send char, using transparancy */
byte ch;
{
switch (ch) /* see what we've got here */
{
/* basic l0 transparancy for flag & escape */
case AFT_FLAG: case AFT_DLE:
#if AFTLEVEL1
/* level 1 transparancy for xon/xoff */
case XON: case XOFF:
#endif
/* first, */
aftt_send_bin( AFT_DLE ); /* send escape char */
ch ^= 0x20 ; /* then xor the char to convert it */
/* then fall through to default to send xvtd char */
default:
aftt_send_bin( ch ); /* send the resulting */
break;
}
}
int cdecl aftt_send( msg ) /* enter with itm; returns 0 if err, !0 if ok */
struct itm_struct *msg;
{
byte cksum, *dptr; /* checksum accum, ptr to data */
word len ;
int retstat ; /* return code */
byte *c ; /* frame tracing*/
len = msg->msg_len ; /* length of data in itm */
if ( len > 0 ) /* if more than 0 bytes */
{
cksum = 0 ; /* initialize cksum */
dptr = msg->itm_data ; /* init ptr to 1st data byte in msg */
aftt_send_bin( AFT_FLAG ) ; /* send opening flag */
while ( len-- > 0 ) /* while characters to send */
{
cksum += *dptr ; /* add value to cksum accum */
aftt_send_data( *dptr++) ; /* and send the char */
}
aftt_send_data( -cksum ); /* now send cksum byte */
aftt_send_bin( AFT_FLAG ); /* and closing flag */
retstat = TRUE ;
#if AFT_FRAME_TRACE
/* take out for now if 0*/
/* just display to console */
c = msg->itm_data; /* set ptr */
printf("sent frame len %d DLC %02X lcn %d cmd $%02X\n",
msg->msg_len ,
*c, *(c+1),*(c+2));
len = msg->msg_len - 1 ; /* take off DLC cmd */
c += 1;
while ( len-- )
{
printf("%02X,'%c'|", *c, ( *c >= 0x20 ? *c: 0x20 ) );
++c;
}
putchar('\n');
#endif
}
else /* error - datalen was 0 */
retstat = FALSE ;
return( retstat );
}